#include "abs.h"

Abs::Abs(QObject *parent)
    :QAbstractVideoSurface(parent)
{
    QCameraInfo info = QCameraInfo::defaultCamera();// 用来获取当前设备当中，默认摄像头的信息
    //QList<QCameraInfo> info_list = QCameraInfo::availableCameras();// 获取当前设备中，所有可用的摄像头信息

    camera = new QCamera(info,this);// 根据获取到的摄像头信息，构建一个摄像头管理对象 camera，该对象未来用来打开或关闭摄像头
    camera->setViewfinder(this);// 将camera拍摄到的画面，交给当前类(Abs类)处理,只要调用了这条代码，摄像头拍摄到的画面，就会自动进入 Abs::present函数中


}

// 摄像头拍摄到的画面，会自动进入present函数，所以我们要在present函数里面写一些简单的处理逻辑
bool Abs::present(const QVideoFrame &frame)
{
    /*
        如何处理摄像头拍摄到的画面
        1:我们要将摄像头拍摄到的画面，发送给userinterface
            可以在 userinterface里面写 函数，用来获取 Abs 里面的图片
            也可以直接通过信号和槽，Abs类通过信号，将图片发送给 userinterface
        2:我们的最终目的，是将图片显示在label上面，label里面，用来设置图片的函数，叫做 setPixmap(QPixmap pic)
            所以我们要做的第2件事情：将QVideoFrame类型的图片，转换成 QPixmap
            QVideoFrame 和 QPixmap 之间，不存在直接转换的路径
            必须借助一个类 QImage，QImage非常好用，他可以将各种各样不同的类型的图片，都转换成QImage
            因为QImage 的构造函数，只需要提供：图片首地址，图片宽度，图片高度，图片每行字节数，图片像素格式
                而这些数据，是一个图片的基本核心数据，不管什么类，只要是图片，都会提供这些数据
            而QImage 可以直接转换成 QPixmap
    */
    QVideoFrame fm = frame;// 拷贝构造一下
    fm.map(QAbstractVideoBuffer::ReadOnly);
    // 上面2条代码唯一的目的，就是为了100%保证，视频流里面的像素数据，允许被访问

    // 将QVideoFrame 图片转换成 QImage
    QImage image(fm.bits(),fm.width(),fm.height(),fm.bytesPerLine(),QImage::Format_RGB32);
    image = image.mirrored(1,1);// 参数2个1表示：横向、纵向都需要镜像一下
    emit sndImage(image); // 将图片通过信号发送给 userinterface

}

// Abs构造函数调用的时候会自动调用这个函数
// 功能是设置Abs类允许处理的像素格式
// 一般来说，通用摄像头拍摄到的画面，他的像素格式 是 rgb32的
// 如果我们不设置的话，Abs 在处理摄像头画面的时候会报错，并告诉用户需要设置 支持 XXX 格式的像素
QList<QVideoFrame::PixelFormat> Abs::supportedPixelFormats(QAbstractVideoBuffer::HandleType type) const
{
    QList<QVideoFrame::PixelFormat> list; // 创建一个允许处理的像素格式的列表
    list << QVideoFrame::Format_RGB32;// 向列表中添加 rgb32 像素格式
    return list;// 向外返回列表，外部或自动获取列表的数据，并设置Abs类允许处理这些像素格式的图片
}

void Abs::camera_start()
{
    camera->start();
}

void Abs::camera_stop()
{
    camera->stop();
}
